/*
 * @Author: Wangjun
 * @Date: 2021-08-16 09:07:58
 * @LastEditTime: 2023-07-31 19:07:07
 * @LastEditors: Wangjun
 * @Description:
 * @FilePath: \golib\js\jstask\task.go
 * hnxr
 */
package jstask

import (
	"time"

	"gitee.com/haodreams/golib/exception"
	"gitee.com/haodreams/golib/logs"
	"gitee.com/haodreams/libs/easy"
	"github.com/dop251/goja"
)

// var thisPtr any

// /**
//  * @description: 设置this的值,必须在加载文件前初始化
//  * @param {any} v
//  * @return {*}
//  */
// func SetThis(v any) {
// 	thisPtr = v
// }

// Task .
type Task struct {
	Time         string //执行时间
	Path         string //路径
	Desc         string //描述
	UsedTime     string //执行任务耗时
	LastCallTime int64  //最后一次调用的开始时间
	Msg          string
	Count        int
	Running      bool //执行状态
	vm           *goja.Runtime
	run          goja.Callable //主循环函数
	ID           int
	this         goja.Value
	Timeout      int64 // 超时时间， 如果超过这个时间还没有执行完，则继续执行
	//initCallback func(vm *goja.Runtime)                                   //回调函数，执行每次的脚本的时候运行
}

// Tasks 任务组
type Tasks struct {
	Time  string
	ID    int
	tasks []*Task
}

// Cancel 取消任务
func (m *Task) Cancel() {
	m.vm = nil
}

// Run 运行任务
func (m *Tasks) Run() {
	for _, task := range m.tasks {
		if task != nil {
			task.Run()
		}
	}
}

// SyncTask 异步
type SyncTask struct {
	taskMap map[string]*Tasks
	array   []*Task
}

// GetTasks 获取全部的任务
func (m *SyncTask) GetTasks() []*Task {
	return m.array
}

// AsyncTask 异步
type AsyncTask struct {
	Tasks
}

// GetTasks 获取全部的任务
func (m *AsyncTask) GetTasks() []*Task {
	return m.tasks
}

func (m *Task) Run() {
	m.work()
	m.Count++
}

// Run 定时执行
func (m *Task) work() {
	now := time.Now()
	if m.Running {
		timeout := easy.IF(m.Timeout == 0, 3600, m.Timeout)
		if now.Unix()-timeout < m.LastCallTime {
			logs.Warn(m.Path, m.Desc, "服务尚未完成, 本次放弃执行")
			return
		}
	}
	m.LastCallTime = now.Unix()
	m.Running = true
	defer func() {
		exception.CatchException()
		m.Running = false
		m.UsedTime = time.Since(now).String()
	}()
	if m.vm != nil && m.run != nil {
		data, err := m.run(m.this)
		if err != nil {
			logs.Warn(m.Path, m.Desc, err)
			m.Msg = err.Error()
			return
		}
		if data == goja.Undefined() {
			return
		}
		m.Msg = data.String()
	}
}
